import 'dart:async';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_jl_bluetooth_plugin/flutter_jl_bluetooth_plugin.dart';
import 'package:flutter_jl_bluetooth/widgets/common_widgets.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_jl_bluetooth_plugin/model/jl_peripheral_model.dart';

class UpgradePage extends StatefulWidget {
  @override
  UpgradePageState createState() => new UpgradePageState();
}

class UpgradePageState extends State<UpgradePage> {
  bool _deviceConnected = false;
  List _otaFileList = [];
  String _selectOtaFilePath = '';
  String _updateText = '';
  JLOtaUpgradeState _state = JLOtaUpgradeState.other;
  double _updateProgressValue = 0;
  Timer? _otaTimer;
  int _otaTimeoutCount = 0;
  bool _isUpgrading = false;
  String _otaFileDocPath = 'upgrade';
  // 若_otaFileDocPath为空字符串则原生层默认赋值为upgrade
  // iOS：/AppData/Documents/$_otaFileDocPath
  // Android：
  // 1.If the Android phone is Running Android 10.0+, put it in /Android/data/\"your package name\"/files/\"your package name\"/$_otaFileDocPath/
  // 2.If the Android phone is running Android 10.0 or below, put it in /\"your package name\"/$_otaFileDocPath/
  String _otaFileDocPathAndroidTip = "";
  String _otaFileDocPathiOSTip = "";

  @override
  void initState() {
    _otaFileDocPathAndroidTip =
    "Please put the upgrade file [xxx.ufw or xxx.bfu] in the storage of the mobile phone.\n\n"
        "1.If the Android phone is Running Android 10.0+, put it in /Android/data/\"your package name\"/files/\"your package name\"/$_otaFileDocPath/\n\n"
        "2.If the Android phone is running Android 10.0 or below, put it in /\"your package name\"/$_otaFileDocPath/";
    _otaFileDocPathiOSTip =
    "Please put the upgrade file [xxx.ufw or xxx.bfu] in the storage of the mobile phone.\n\nPut it in /AppData/Documents/$_otaFileDocPath";
    FlutterJlBluetoothPlugin.deviceConnectCallback = (JLPeripheralState state) {
      switch (state) {
        case JLPeripheralState.connected:
          _deviceConnected = true;
          break;
        case JLPeripheralState.disconnected:
          _deviceConnected = false;
          break;
        case JLPeripheralState.refuse:
          _deviceConnected = false;
          break;
        default:
          print("deviceConnectCallback default: $state");
          break;
      }
      if (mounted) setState(() {});
    };

    /// ota升级进度回调
    FlutterJlBluetoothPlugin.otaUpgradeProgressCallback =
        (JLOtaUpgradeState state, double progress) {
      _state = state;
      switch (_state) {
        case JLOtaUpgradeState.preparing:
          _updateProgressValue = progress;
          checkOtaUpgradeTimeout();
          break;
        case JLOtaUpgradeState.upgrading:
          _updateText = '升级进度：';
          _updateProgressValue = progress;
          _isUpgrading = true;
          checkOtaUpgradeTimeout();
          break;
        case JLOtaUpgradeState.prepared:
          checkOtaUpgradeTimeout();
          break;
        case JLOtaUpgradeState.reconnect:
          cancelCheckOtaUpgradeTimeout();
          break;
        case JLOtaUpgradeState.success:
          cancelCheckOtaUpgradeTimeout();
          _updateText = '升级完成';
          _updateProgressValue = 1;
          _isUpgrading = false;
          Future.delayed(Duration(seconds: 2), () async {
            _deviceConnected =
            await FlutterJlBluetoothPlugin().bleDeviceConnected;
            if (mounted) setState(() {});
          });
          break;
        case JLOtaUpgradeState.failed:
          _updateText = '升级失败';
          Fluttertoast.showToast(
            msg: "升级失败",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
          _updateProgressValue = 0;
          _isUpgrading = false;
          break;
        case JLOtaUpgradeState.fileKeyError:
          _updateText = '升级文件key错误';
          Fluttertoast.showToast(
            msg: "升级文件key错误",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
          _updateProgressValue = 0;
          _isUpgrading = false;
          break;
        case JLOtaUpgradeState.fileError:
          _updateText = '升级文件错误';
          Fluttertoast.showToast(
            msg: "升级文件错误",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
          _updateProgressValue = 0;
          _isUpgrading = false;
          break;
        case JLOtaUpgradeState.readyToRestart:
          Fluttertoast.showToast(
            msg: "设备准备重启",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
          _isUpgrading = false;
          break;
        default:
          cancelCheckOtaUpgradeTimeout();
          break;
      }
      if (mounted) setState(() {});
    };
    Future.delayed(Duration(seconds: 0), () async {
      await FlutterJlBluetoothPlugin().startScanBleDevice();
      _deviceConnected = await FlutterJlBluetoothPlugin().bleDeviceConnected;
      _otaFileList =
      await FlutterJlBluetoothPlugin().otaFileList(_otaFileDocPath);
      String selectOtaFilePath =
      await FlutterJlBluetoothPlugin().selectOtaFilePath;
      List<String> selectOtaFilePathList = selectOtaFilePath.split("/");
      _selectOtaFilePath = selectOtaFilePathList.last;
      if (mounted) setState(() {});
    });
    super.initState();
  }

  @override
  void dispose() {
    cancelCheckOtaUpgradeTimeout();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color.fromRGBO(231, 231, 231, 1),
      appBar: AppBar(
        backgroundColor: Colors.blueAccent,
        title: Text("设备升级"),
      ),
      body: Column(
        children: [
          Container(
            margin: EdgeInsets.only(
              left: 8,
              right: 8,
            ),
            height: 50,
            child: Row(
              children: [
                Text("设备状态："),
                Text(
                  _deviceConnected ? '已连接' : '未连接',
                  style: TextStyle(
                      color:
                      _deviceConnected ? Colors.blueAccent : Colors.grey),
                ),
              ],
            ),
          ),
          Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(8)),
              color: Colors.white,
            ),
            margin: EdgeInsets.only(
              // top: 8,
              left: 8,
              right: 8,
            ),
            height: MediaQuery.of(context).size.height - 50 - 20 - 50 - 150,
            child: Column(
              children: [
                Container(
                  margin: EdgeInsets.only(top: 8, left: 8),
                  width: MediaQuery.of(context).size.width,
                  child: Text(
                    "文件选择",
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 14,
                    ),
                  ),
                ),
                (_otaFileList.length > 0)
                    ? Expanded(
                  child: ListView.builder(
                    itemCount: _otaFileList.length,
                    itemBuilder: (BuildContext context, int index) {
                      return _fileWidget(context, index);
                    },
                  ),
                )
                    : Container(
                  margin: EdgeInsets.only(
                    top: 8,
                    left: 8,
                    right: 8,
                  ),
                  width: MediaQuery.of(context).size.width,
                  child: Platform.isIOS
                      ? Text(_otaFileDocPathiOSTip)
                      : Text(_otaFileDocPathAndroidTip),
                ),
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.only(top: 8, left: 8, right: 8),
            width: MediaQuery.of(context).size.width,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  _updateText,
                  style: TextStyle(
                    fontSize: 14,
                  ),
                ),
                Text(
                  _updateText.length != 0
                      ? "${(_updateProgressValue * 100.0).toStringAsFixed(2)}%"
                      : '',
                  style: TextStyle(
                    color: Colors.blueAccent,
                    fontSize: 14,
                  ),
                )
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.only(top: 8, left: 8, right: 8),
            child: LinearProgressIndicator(
              value: _updateProgressValue,
            ),
          ),
          Container(
            margin: EdgeInsets.only(top: 8, left: 8, right: 8),
            child: ElevatedButton(
              child: Container(
                width: MediaQuery.of(context).size.width,
                height: 50,
                child: Center(
                  child: Text("设备升级"),
                ),
              ),
              onPressed: () async {
                if (_isUpgrading == true) {
                  Fluttertoast.showToast(
                    msg: "升级进行中，请勿重复点击！",
                    toastLength: Toast.LENGTH_SHORT,
                    gravity: ToastGravity.CENTER,
                    timeInSecForIosWeb: 1,
                    fontSize: 16.0,
                  );
                  setState(() {});
                  return;
                }
                _deviceConnected =
                await FlutterJlBluetoothPlugin().bleDeviceConnected;
                if (_deviceConnected == false) {
                  Fluttertoast.showToast(
                    msg: "请先进行设备连接",
                    toastLength: Toast.LENGTH_SHORT,
                    gravity: ToastGravity.CENTER,
                    timeInSecForIosWeb: 1,
                    fontSize: 16.0,
                  );
                  setState(() {});
                  return;
                }
                if (_selectOtaFilePath.length == 0) {
                  Fluttertoast.showToast(
                    msg: "请选择文件",
                    toastLength: Toast.LENGTH_SHORT,
                    gravity: ToastGravity.CENTER,
                    timeInSecForIosWeb: 1,
                    fontSize: 16.0,
                  );
                  return;
                }
                await FlutterJlBluetoothPlugin()
                    .setSelectOtaFilePath(_selectOtaFilePath);
                await FlutterJlBluetoothPlugin()
                    .getBleDeviceInfoAndStartOtaUpgrade();
                _isUpgrading = true;
                setState(() {});
              },
            ),
          ),
        ],
      ),
    );
  }

  /// 文件widget
  Widget _fileWidget(BuildContext context, int index) {
    String filePath = _otaFileList[index];
    return Container(
      height: 50,
      padding: const EdgeInsets.only(
        left: 8,
        right: 8,
      ),
      child: Column(
        children: [
          Container(
            height: 49,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Container(
                  width: 250,
                  child: Text(
                    filePath,
                    maxLines: 1,
                    textDirection: TextDirection.ltr,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(fontSize: 16),
                  ),
                ),
                IconButton(
                  onPressed: () async {
                    if (_isUpgrading == true) {
                      return;
                    }
                    if (_selectOtaFilePath == filePath) {
                      _selectOtaFilePath = '';
                    } else {
                      _selectOtaFilePath = filePath;
                    }
                    await FlutterJlBluetoothPlugin()
                        .setSelectOtaFilePath(_selectOtaFilePath);
                    setState(() {});
                  },
                  icon: Icon(
                    Icons.check,
                    color: _selectOtaFilePath == filePath
                        ? Colors.blueAccent
                        : Colors.grey,
                  ),
                ),
              ],
            ),
          ),
          bottomWidget(),
        ],
      ),
    );
  }

  void checkOtaUpgradeTimeout() {
    _otaTimeoutCount = 0;
    if (_otaTimer == null) {
      _otaTimer = Timer.periodic(Duration(seconds: 1), (timer) {
        _otaTimeoutCount++;
        if (_otaTimeoutCount == 10) {
          cancelCheckOtaUpgradeTimeout();
          print('OTA ---> 超时了！！！');
          _updateText = '';
          Fluttertoast.showToast(
            msg: "升级超时",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
        }
      });
    }
  }

  void cancelCheckOtaUpgradeTimeout() {
    _otaTimeoutCount = 0;
    if (_otaTimer != null) {
      _otaTimer!.cancel();
      _otaTimer = null;
    }
  }
}
